#include "funcionesCompartidas.h"
#include "logic.h"
#include "dataStructure.h"
#include "design.h"

/*Esta estructura de datos me parecio la ideal para este caso particular:
-Una lista doblemente enlazada que coloca los nuevos items al final de la lista*/

/* Estos son los dos punteros a la lista enlazada */
struct obstacle * startPtr = NULL;
static struct obstacle * lastPtr = NULL;

/* Borramos todos los elementos de la lista enlazada */
void resetStructures()
{
	struct obstacle * aux;

	while(lastPtr) {
		aux = lastPtr->prior;
		linkedListDeleteNode(lastPtr);
		lastPtr = aux;
	}

	startPtr = NULL;
	lastPtr = NULL;
	
	generateCar();

}

/* Retornamos la cantidad de nodos de la lista */
int linkedListNumberOfNodes()
{
	int i = 0;
	struct obstacle * auxPtr = lastPtr;

	while(auxPtr){
		i++;
		auxPtr = auxPtr->prior;
	}

	return i;
}

/* Mostramos la lista enlazada completa*/
void linkedListDisplay()
{
	struct obstacle * startPtrAux = startPtr;

	int i = 0;
	while(startPtrAux) {
		startPtrAux = startPtrAux->next;
		i++;
	}
	printf("La cantidad de nodos en la lista es de: %d\n", i);
}

/* Creamos un nuevo obstaculo y seteamos sus valores basicos */
struct obstacle * newObstacle(float red, float green, float blue, int tipoObjeto){
	struct obstacle * newItem = NULL;

	if( !(newItem = (struct obstacle *)malloc(1*sizeof(struct obstacle))) ){
		printf("No hay suficiente memoria\n");
		exit(-1);
	}

	/* Inicializamos la profundidad del objeto */
	newItem->profundidad = PROFUNDIDAD_INICIAL;
	/* Inicializamos el color del objeto */
	newItem->rgbColour[0] = red;
	newItem->rgbColour[1] = green;
	newItem->rgbColour[2] = blue;
	/* Seteamos el tipo de objeto */
	newItem->tipo = tipoObjeto;

	/* Seteamos la coordenada x donde se dibujara el objeto */
	newItem->xCoordinate = xCoordinateRandom();

	return newItem;
}


/* Adjuntamos un nuevo item al final de la lista enlazada */
void linkedListStoreNode(struct obstacle *i)
{
	if(!lastPtr){ 
	  lastPtr = i; /* is first item in list */
	  i->prior = NULL;
	  startPtr = lastPtr;
	}else {
        lastPtr->next = i;
		i->prior = lastPtr;
	}
  i->next = NULL;

  lastPtr = i;
}

/* Eliminamos el nodo indicado de la lista enlazada */
void linkedListDeleteNode(struct obstacle *i)/* item to delete */
{
  if(i->prior) /* Si el nodo estaba entre otros dos nodos */ 
	  i->prior->next = i->next;
  else{ /* va haber un nuevo primer nodo */
    startPtr = i->next;
    if(startPtr) /* si no queda vacia la lista ponemos NULL al prior del primer nodo */
		(startPtr)->prior = NULL;
  }

  if(i->next) 
     i->next->prior = i->prior;
  else   /* deleting last element */
    lastPtr = i->prior;

  free(i);

}
